package com.liyujie.serialport.utils;

import android.util.Log;

import com.blankj.utilcode.util.ConvertUtils;

import java.io.File;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

import me.f1reking.serialportlib.SerialPortHelper;
import me.f1reking.serialportlib.entity.DATAB;
import me.f1reking.serialportlib.entity.FLOWCON;
import me.f1reking.serialportlib.entity.PARITY;
import me.f1reking.serialportlib.entity.STOPB;
import me.f1reking.serialportlib.listener.IOpenSerialPortListener;
import me.f1reking.serialportlib.listener.ISerialPortDataListener;
import me.f1reking.serialportlib.listener.Status;


/**
 *开门串口
 */
public class OpenSerialportUtils {

    public static SerialPortHelper serialPortHelper;
    private static  final Semaphore semaphore=new Semaphore(0,true);
    private  static byte[] receiveBuff = null;

    /**
     * 初始化串口
     */
    public static void initializationSerialPort() {
        serialPortHelper = new SerialPortHelper();
        serialPortHelper.setIOpenSerialPortListener(new IOpenSerialPortListener() {
            @Override
            public void onSuccess(File device) {
                Log.d("OpenSerialportUtils","成功"+device.getPath());
            }

            @Override
            public void onFail(File device, Status status) {
                switch (status) {
                    case NO_READ_WRITE_PERMISSION:
                        Log.d("OpenSerialportUtils",device.getPath() + " :没有读写权限");
                        break;
                    case OPEN_FAIL:
                    default:
                        Log.d("OpenSerialportUtils",device.getPath() + " :串口打开失败");
                        break;
                }
            }
        });
    }

    /**
     * 打开开门串口
     * 打开开门串口
     * 打开开门串口
     * @param serialPortAddress
     * @return
     */
    public static boolean openOpenSerialPort(String serialPortAddress){
        boolean whetherOpen = false;
        //打开串口
        if(null != serialPortHelper){
            if(serialPortHelper.isOpen()){
                Log.d("OpenSerialportUtils","打开开门串口");
                whetherOpen = true;
            }else {
                serialPortHelper.setPort(serialPortAddress);
                serialPortHelper.setBaudRate(9600);
                serialPortHelper.setStopBits(STOPB.getStopBit(STOPB.B1));
                serialPortHelper.setDataBits(DATAB.getDataBit(DATAB.CS8));
                serialPortHelper.setParity(PARITY.getParity(PARITY.NONE));
                serialPortHelper.setFlowCon(FLOWCON.getFlowCon(FLOWCON.NONE));
                //定义串口数据接收回调
                serialPortHelper.setISerialPortDataListener(new ISerialPortDataListener() {
                    @Override
                    public void onDataReceived(byte[] bytes) {
                        receiveBuff=new byte[bytes.length];
                        System.arraycopy(bytes,0,receiveBuff,0,bytes.length);
                        semaphore.release();
                    }

                    @Override
                    public void onDataSend(byte[] bytes) {

                    }
                });
                if(serialPortHelper.open()){
                    whetherOpen = true;
                    Log.d("OpenSerialportUtils","开门串口开启成功");
                }else {
                    whetherOpen = false;
                    Log.d("OpenSerialportUtils","开门串口开启失败");
                }
            }
        }
        return whetherOpen;
    }


    /**
     * 设置锁板
     * @param door
     * @param cmd 0开门  1是开始编号  2是结束编号 3 查询门状态
     */
    public static boolean sendData(Byte door, String cmd){
        boolean Senddata = false;
        byte[] sendContentBytes = new byte[6];
        sendContentBytes[0] = door; //设备地址
        sendContentBytes[1] =  Byte.valueOf(cmd);//命令
        sendContentBytes[2] = 1; //桢序列
        sendContentBytes[3] = 1;////数据长度
        sendContentBytes[4] =  door; //数据在和
        sendContentBytes[5] =(byte)( 0 - sendContentBytes[0] - sendContentBytes[1] - sendContentBytes[2] - sendContentBytes[3] - sendContentBytes[4]); //校验
        if (serialPortHelper != null) {
            Senddata = serialPortHelper.sendBytes(sendContentBytes);
        }
        Log.d("OpenSerialportUtils","编号发送的数据" + ConvertUtils.bytes2HexString(sendContentBytes));
        return Senddata;
    }



    /**
     * 开门，且自动重发
     * @param event
     * @return  返回串口收到的正确结果
     */
    public static boolean sendOpenCommand(byte event) throws InterruptedException {
        boolean res = false;
        byte[] sendContentBytes = new byte[6];
        sendContentBytes[0] = event; //设备地址
        sendContentBytes[1] = 0;//命令
        sendContentBytes[2] = 1; //桢序列
        sendContentBytes[3] = 1;////数据长度
        sendContentBytes[4] = event; //数据在和
        sendContentBytes[5] =(byte)( 0 - sendContentBytes[0] - sendContentBytes[1] - sendContentBytes[2] - sendContentBytes[3] - sendContentBytes[4]); //校验
        int cnt = 1;  //定义重发次数
        if (serialPortHelper != null) {
            do {
                receiveBuff=null;
                while(semaphore.tryAcquire());
                //发送开门命令
                if(serialPortHelper.sendBytes(sendContentBytes)){
                    //从queue中获取串口收到的数据
                    if(semaphore.tryAcquire(800, TimeUnit.MILLISECONDS)) {
                        if (receiveBuff != null) {
                            //判断校验合
                            byte sum = 0;
                            if ((sum == 0  && receiveBuff.length == 7)||(receiveBuff[0] == event && receiveBuff.length == 1)) {
                                res=true;
                                break;
                            } else {
                                semaphore.tryAcquire(300, TimeUnit.MILLISECONDS);//收到消息不对，延时300ms重发
                            }
                        } else{
                            semaphore.tryAcquire(300, TimeUnit.MILLISECONDS);//收到消息不对，延时300ms重发
                        }
                    } else {
                    }
                }else {
                    break;
                }
                //否则重发数据
                cnt--;
            }while (cnt > 0);
        }
        Log.d("OpenSerialportUtils",ConvertUtils.bytes2HexString(sendContentBytes));
        return  res;
    }



    /**
     * 获得所有串口设备的地址
     * @return
     */
    public static String[] getAllDeicesPath(){
        if (serialPortHelper == null) {
            return null;
        }else {
            return serialPortHelper.getAllDeicesPath();
        }
    }

    /**
     * 关闭
     */
    public static void closeSerialPort(){
        if(null != serialPortHelper){
            serialPortHelper.close();
        }
    }


}
